// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#include <nebula/compute/kernels/util_internal.h>

#include <cstdint>

#include <nebula/array/data.h>
#include <nebula/compute/function.h>
#include <nebula/types/type.h>
#include <turbo/base/checked_cast.h>

namespace nebula::compute::internal {

    namespace {

        turbo::Status NullToNullExec(KernelContext *ctx, const ExecSpan &batch, ExecResult *out) {
            return turbo::OkStatus();
        }

    }  // namespace

    ExecValue GetExecValue(const Datum &value) {
        ExecValue result;
        if (value.is_array()) {
            result.set_array(*value.array());
        } else {
            result.set_scalar(value.scalar().get());
        }
        return result;
    }

    int64_t GetTrueCount(const ArraySpan &mask) {
        if (mask.buffers[0].data != nullptr) {
            return CountAndSetBits(mask.buffers[0].data, mask.offset, mask.buffers[1].data,
                                   mask.offset, mask.length);
        } else {
            return CountSetBits(mask.buffers[1].data, mask.offset, mask.length);
        }
    }

    void add_null_exec(ScalarFunction *func) {
        std::vector<InputType> input_types(func->arity().num_args, InputType(Type::NA));
        KCHECK_OK(func->add_kernel(std::move(input_types), OutputType(null()), NullToNullExec));
    }


}  // namespace nebula::compute::internal
